home *** CD-ROM | disk | FTP | other *** search
/ ShareWare OnLine 2 / ShareWare OnLine Volume 2 (CMS Software)(1993).iso / prog / strpp212.zip / STR.CPP < prev    next >
C/C++ Source or Header  |  1993-02-17  |  11KB  |  564 lines

  1. /* -------------------------------------------------------------------- */
  2. /* String++ Version 2.12                                       02/16/93 */
  3. /*                                                                      */
  4. /* Enhanced string class for Turbo C++/Borland C++.                     */
  5. /* Copyright 1991-1993 by Carl W. Moreland                              */
  6. /*                                                                      */
  7. /* str.cpp                                                              */
  8. /* -------------------------------------------------------------------- */
  9.  
  10. #include <ctype.h>
  11. #include <stdlib.h>
  12. #include "str.h"
  13.  
  14. /* ----- Constructors/Destructors ------------------------------------- */
  15.  
  16. string::string()
  17. {
  18.   _ptr = new char[1];            // NULL string
  19.   _ptr[0] = '\0';
  20. }
  21.  
  22. string::string(const char c, unsigned n)
  23. {
  24.   _ptr = new char[n+1];            // allocate memory for n chars
  25.  
  26.   for(int i=0; i<n; i++)
  27.     _ptr[i] = c;             // copy n chars
  28.   _ptr[i] = '\0';            // NULL terminate
  29. }
  30.  
  31. string::string(const char* s, unsigned pos, unsigned len)
  32. {
  33.   int s_len = strlen(s);
  34.  
  35.   if(pos > s_len)
  36.     pos = s_len;
  37.   if(len > s_len - pos)
  38.     len = s_len - pos;
  39.  
  40.   _ptr = new char[len+1];        // allocate new memory
  41.  
  42.   strncpy(_ptr, s+pos, len);        // copy the substring
  43.   _ptr[len] = '\0';            // need to NULL terminate
  44. }
  45.  
  46. string::string(const string& s, unsigned pos, unsigned len)
  47. {
  48.   int s_len = s.Len();
  49.  
  50.   if(pos > s_len)
  51.     pos = s_len;
  52.   if(len > s_len - pos)
  53.     len = s_len - pos;
  54.  
  55.   _ptr = new char[len+1];        // allocate new memory
  56.  
  57.   strncpy(_ptr, s(pos), len);        // copy the substring
  58.   _ptr[len] = '\0';            // need to NULL terminate
  59. }
  60.  
  61. void string::ltos(long n)
  62. {
  63.   char tmp[15];
  64.   ltoa(n, tmp, 10);
  65.  
  66.   _ptr = new char[strlen(tmp) + 1];
  67.   strcpy(_ptr, tmp);
  68. }
  69.  
  70. string::~string(void)
  71. {
  72.   if(_ptr)
  73.     delete _ptr;
  74. }
  75.  
  76. /* -------------------------------------------------------------------- */
  77.  
  78. string& string::Right(unsigned len)
  79. {
  80.   Mid(this->Len()-len, len);
  81.   return *this;
  82. }
  83.  
  84. string& string::Left(unsigned len)
  85. {
  86.   Mid(0, len);
  87.   return *this;
  88. }
  89.  
  90. string& string::Mid(unsigned pos, unsigned len)
  91. {
  92.   int s_len = Len();
  93.  
  94.   if(pos > s_len)
  95.     pos = s_len;
  96.   if(len > s_len - pos)
  97.     len = s_len - pos;
  98.  
  99.   char *tmp = new char[len+1];        // allocate new memory
  100.  
  101.   strncpy(tmp, _ptr+pos, len);        // copy the substring
  102.   tmp[len] = '\0';            // need to NULL terminate
  103.  
  104.   delete _ptr;
  105.   _ptr = tmp;
  106.   return *this;
  107. }
  108.  
  109. string& string::Justify(int mode, unsigned len, int clip)
  110. {
  111.   Trim();                // delete outter whitespace
  112.  
  113.   int this_len = Len();
  114.  
  115.   if(this_len >= len && clip == 0)    // check for out-of-bounds
  116.     return *this;
  117.  
  118.   if(this_len > len && clip == 1)    // check for clipping
  119.   {
  120.     if(mode == LEFT)
  121.       Left(len);
  122.     else if(mode == CENTER)
  123.       Mid((this_len-len)/2, len);
  124.     else if(mode == RIGHT)
  125.       Right(len);
  126.  
  127.     return *this;            // return clipped string
  128.   }
  129.  
  130.   if(mode == LEFT)
  131.     *this = *this + string(' ', len-this_len);
  132.   else if(mode == CENTER)
  133.     *this = string(' ', (len-this_len)/2) + *this + string(' ', len - (len+this_len)/2);
  134.   else if(mode == RIGHT)
  135.     *this = string(' ', len-this_len) + *this;
  136.  
  137.   return *this;                // return normal string
  138. }
  139.  
  140. string& string::toUpper(void)
  141. {
  142.   for(int i=0; i<strlen(_ptr); i++)
  143.     _ptr[i] = ::toupper(_ptr[i]);
  144.   return *this;
  145. }
  146.  
  147. string& string::toLower(void)
  148. {
  149.   for(int i=0; i<strlen(_ptr); i++)
  150.     _ptr[i] = ::tolower(_ptr[i]);
  151.   return *this;
  152. }
  153.  
  154. int& string::Value(int& n)
  155. {
  156.   n = atoi(_ptr);
  157.   return n;
  158. }
  159.  
  160. long& string::Value(long& n)
  161. {
  162.   n = atol(_ptr);
  163.   return n;
  164. }
  165.  
  166. string& string::Insert(unsigned pos, const string& s)
  167. {
  168.   int this_len = this->Len();
  169.   int s_len = s.Len();
  170.  
  171.   if(pos > this_len)
  172.     pos = this_len;
  173.  
  174.   char *tmp = new char[this_len + s_len + 1];
  175.  
  176.   strncpy(tmp, _ptr, pos);
  177.   tmp[pos] = '\0';
  178.   strcat(tmp, s.ptr());
  179.   strcat(tmp, _ptr+pos);
  180.  
  181.   delete _ptr;
  182.   _ptr = tmp;
  183.   return *this;
  184. }
  185.  
  186. string& string::Delete(unsigned pos, unsigned len)
  187. {
  188.   int this_len = this->Len();
  189.  
  190.   if(pos >= this_len)
  191.     return *this;
  192.   if(len == 0)
  193.     return *this;
  194.   if(len > this_len - pos)
  195.     len = this_len - pos;
  196.  
  197.   char *tmp = new char[this_len-len+1];
  198.  
  199.   strncpy(tmp, _ptr, pos);
  200.   tmp[pos] = '\0';
  201.   strcat(tmp, _ptr+pos+len);
  202.  
  203.   delete _ptr;
  204.   _ptr = tmp;
  205.   return *this;
  206. }
  207.  
  208. char* string::Copy(char*& s)
  209. {
  210.   s = new char[Len() + 1];
  211.   strcpy(s, _ptr);
  212.  
  213.   return s;
  214. }
  215.  
  216. string& string::Trim(int mode, char ch)
  217. {
  218.   int begin = 0;
  219.   int end = this->Len()-1;
  220.  
  221.   if(ch == WHITESPACE)            // if we're deleting whitespaces...
  222.   {
  223.     if(mode == LEFT || mode == CENTER)    // delete leading whitespace
  224.     {
  225.       while(isspace(_ptr[begin]) && begin <= end)
  226.         begin++;
  227.     }
  228.  
  229.     if(mode == RIGHT || mode == CENTER)    // delete trailing whitespace
  230.     {
  231.       while(isspace(_ptr[end]) && end >= begin)
  232.         end--;
  233.     }
  234.   }
  235.   else                    // else a character was specified
  236.   {
  237.     if(mode == LEFT || mode == CENTER)    // delete leading characters
  238.     {
  239.       while(_ptr[begin] == ch && begin <= end)
  240.         begin++;
  241.     }
  242.  
  243.     if(mode == RIGHT || mode == CENTER)    // delete trailing characters
  244.     {
  245.       while(_ptr[end] == ch && end >= begin)
  246.         end--;
  247.     }
  248.   }
  249.  
  250.   int s_len = end-begin+1;
  251.   char *tmp = new char[s_len + 1];
  252.   strncpy(tmp, _ptr+begin, s_len);
  253.   tmp[s_len] = '\0';
  254.  
  255.   delete _ptr;
  256.   _ptr = tmp;
  257.   return *this;
  258. }
  259.  
  260. /* ----- Operators ---------------------------------------------------- */
  261.  
  262. string string::operator()(unsigned pos, unsigned len) const
  263. {
  264.   string tmp(this->_ptr, pos, len);
  265.   return tmp;
  266. }
  267.  
  268. // =
  269. string& string::operator=(const char ch)
  270. {
  271.   if(_ptr)
  272.     delete _ptr;
  273.  
  274.   _ptr = new char[2];
  275.   _ptr[0] = ch;
  276.   _ptr[1] = '\0';
  277.  
  278.   return *this;
  279. }
  280.  
  281. string& string::operator=(const char *s)
  282. {
  283.   char *tmp = _ptr;            // don't delete _ptr yet
  284.   _ptr = new char[strlen(s)+1];
  285.   strcpy(_ptr, s);
  286.  
  287.   if(tmp)
  288.     delete tmp;
  289.   return *this;
  290. }
  291.  
  292. string& string::operator=(const string& s)
  293. {
  294.   char *tmp = _ptr;            // don't delete _ptr yet
  295.   _ptr = new char[s.Len()+1];
  296.   strcpy(_ptr, s.ptr());
  297.  
  298.   if(tmp)
  299.     delete tmp;
  300.   return *this;
  301. }
  302.  
  303. string& string::operator=(const int n)
  304. {
  305.   if(_ptr)
  306.     delete _ptr;
  307.  
  308.   char tmp[15];
  309.   itoa(n, tmp, 10);
  310.  
  311.   _ptr = new char[strlen(tmp) + 1];
  312.   strcpy(_ptr, tmp);
  313.  
  314.   return *this;
  315. }
  316.  
  317. // +
  318. string operator+(const string& s1, const char *s2)
  319. {
  320.   string tmp(s1);
  321.   tmp += s2;
  322.   return tmp;
  323. }
  324.  
  325. string operator+(const char *s1, const string& s2)
  326. {
  327.   string tmp(s1);
  328.   tmp += s2;
  329.   return tmp;
  330. }
  331.  
  332. string operator+(const string& s1, const string& s2)
  333. {
  334.   string tmp(s1);
  335.   tmp += s2;
  336.   return tmp;
  337. }
  338.  
  339. // +=
  340. string& string::operator+=(const char ch)
  341. {
  342.   char *tmp = _ptr;
  343.   int this_len = this->Len();
  344.  
  345.   _ptr = new char[this_len + 2];
  346.  
  347.   strcpy(_ptr, tmp);
  348.   _ptr[this_len]   = ch;
  349.   _ptr[this_len+1] = '\0';
  350.  
  351.   if(tmp)
  352.     delete tmp;
  353.   return *this;
  354. }
  355.  
  356. string& string::operator+=(const char *s)
  357. {
  358.   char *tmp = _ptr;
  359.  
  360.   _ptr = new char[strlen(tmp) + strlen(s) + 1];
  361.  
  362.   strcpy(_ptr, tmp);
  363.   strcat(_ptr, s);
  364.  
  365.   if(tmp)
  366.     delete tmp;
  367.   return *this;
  368. }
  369.  
  370. string& string::operator+=(const string& s)
  371. {
  372.   char *tmp = _ptr;
  373.   _ptr = new char[strlen(tmp) + s.Len() + 1];
  374.  
  375.   strcpy(_ptr, tmp);
  376.   strcat(_ptr, s.ptr());
  377.  
  378.   if(tmp)
  379.     delete tmp;
  380.   return *this;
  381. }
  382.  
  383. // *
  384. string operator*(const string& s1, int n)
  385. {
  386.   string tmp(s1);
  387.  
  388.   for(int i=1; i<n; i++)
  389.     tmp += s1;
  390.   return tmp;
  391. }
  392.  
  393. // *=
  394. string& string::operator*=(unsigned n)
  395. {
  396.   char *tmp = _ptr;
  397.  
  398.   _ptr = new char[n*strlen(tmp) + 1];
  399.  
  400.   strcpy(_ptr, tmp);
  401.   for(int i=1; i<n; i++)
  402.     strcat(_ptr, tmp);
  403.  
  404.   if(tmp)
  405.     delete tmp;
  406.   return *this;
  407. }
  408.  
  409. // []
  410. char& string::operator[](unsigned n) const
  411. {
  412.   if(n >= Len())
  413.     n = Len()-1;
  414.   return *(_ptr + n);
  415. }
  416.  
  417. /* -------------------------------------------------------------------- */
  418. /* AWK-style functions                                                  */
  419. /* -------------------------------------------------------------------- */
  420.  
  421. int index(const string& s, const string& t)
  422. {
  423.   int pos;
  424.   char *tmp;
  425.  
  426.   if((tmp = strstr(s.ptr(), t.ptr())) != NULL)
  427.     pos = (int)(tmp-(const)s.ptr());
  428.   else
  429.     pos = -1;
  430.  
  431.   return pos;
  432. }
  433.  
  434. string substr(const string& s, unsigned p, unsigned n)
  435. {
  436.   string tmp = mid(s, p, n);
  437.   return tmp;
  438. }
  439.  
  440. int split(const string& s, string*& array, const string& fs)
  441. {
  442.   int i=0, j=1, start=0;
  443.   int fs_len = fs.Len();
  444.   int s_len = s.Len();
  445.   string *tmp;
  446.  
  447.   while(i < s_len)
  448.   {
  449.     if(strncmp(s(i), fs(), fs_len) == 0)
  450.       j++;
  451.     i++;
  452.   }
  453.   tmp = new string[j];
  454.   i = 0;
  455.   j = 0;
  456.  
  457.   while(i < s_len)
  458.   {
  459.     if(strncmp(s(i), fs(), fs_len) == 0)
  460.     {
  461.       tmp[j++] = string(mid(s, start, i-start));
  462.       i += fs_len;
  463.       start = i;
  464.     }
  465.     else
  466.       i++;
  467.   }
  468.   tmp[j++] = mid(s, start, i-start);
  469.  
  470.   array = tmp;
  471.   return j;
  472. }
  473.  
  474. int gsub(const string& from, const string& to, string& str, unsigned count)
  475. {
  476.   int i=0, j=0;
  477.   int from_len, to_len;
  478.  
  479.   from_len = from.Len();
  480.   to_len = to.Len();
  481.  
  482.   while(i <= str.Len()-from_len)
  483.   {
  484.     if(strncmp(str(i), from(), from_len) == 0)
  485.     {
  486.       str = left(str, i) + to + right(str, str.Len()-i-from_len);
  487.       i += to_len;
  488.       if(++j == count)
  489.         break;
  490.     }
  491.     else
  492.       i++;
  493.   }
  494.   return j;
  495. }
  496.  
  497. /* -------------------------------------------------------------------- */
  498. /* C-style functions                            */
  499. /* -------------------------------------------------------------------- */
  500.  
  501. string toupper(const string& s)
  502. {
  503.   string tmp(s);
  504.   tmp.toupper();
  505.   return tmp;
  506. }
  507.  
  508. string tolower(const string& s)
  509. {
  510.   string tmp(s);
  511.   tmp.tolower();
  512.   return tmp;
  513. }
  514.  
  515. string left(const string& s, unsigned len)
  516. {
  517.   string tmp(s, 0, len);
  518.   return tmp;
  519. }
  520.  
  521. string right(const string& s, unsigned len)
  522. {
  523.   string tmp(s, s.Len()-len, len);
  524.   return tmp;
  525. }
  526.  
  527. string mid(const string& s, unsigned pos, unsigned len)
  528. {
  529.   string tmp(s, pos, len);
  530.   return tmp;
  531. }
  532.  
  533. string justify(const string& s, int mode, unsigned len, int clip)
  534. {
  535.   string tmp(s);
  536.   tmp.Justify(mode, len, clip);
  537.   return tmp;
  538. }
  539.  
  540. string trim(const string& s, int mode)
  541. {
  542.   string tmp(s);
  543.   tmp.Trim(mode);
  544.   return tmp;
  545. }
  546.  
  547. /* ----- Stream I/O --------------------------------------------------- */
  548.  
  549. ostream& operator<<(ostream& s, const string& str)
  550. {
  551.   return s << str();
  552. }
  553.  
  554. istream& operator>>(istream& s, string& str)
  555. {
  556.   char p[256];
  557.  
  558.   s >> p;
  559.   str = p;
  560.  
  561.   return s;
  562. }
  563.  
  564.